//This file is a part of StoragePlug for Minecraft.
//http://code.google.com/p/minecraft-storageplug/
//StoragePlug is Copyright (C) 2011 Christopher Smith
//Released under the MIT license:
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights 
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//DEALINGS IN THE SOFTWARE.
//
//Related to Minecraft Copyright (C) 2009-2011 Mojang http://www.minecraft.net/

package net.minecraft.src;

import java.lang.reflect.Constructor;
import java.util.HashMap;

import net.minecraft.storageplug.DataTree;
import net.minecraft.storageplug.Key;
import net.minecraft.storageplug.Key.ItemData;
import net.minecraft.storageplug.StorageProvider;

public class MapStorage
{
	public final StorageProvider provider;
	final HashMap<String, WorldSavedData> loaded;
	
    public MapStorage(ISaveHandler isavehandler)
    {
    	this.provider = ((SaveOldDir)isavehandler).provider;
    	this.loaded = new HashMap<String, WorldSavedData>();
    }

    public WorldSavedData loadData(Class create_class, String s)
    {
		WorldSavedData wsd;

		synchronized(loaded)
		{
			wsd = loaded.get(s);
		}
		
		if(wsd != null)
			return wsd;
    	
    	try
		{    	
    	
	        try
	        {
	            wsd = (WorldSavedData)create_class.getConstructor(new Class[] {java.lang.String.class}).newInstance(new Object[] {s});
	        }
	        catch(Exception e)
	        {
	            throw new RuntimeException("Failed to instantiate " + create_class.toString(), e);
	        }
	        
			DataTree dt = provider.readDataTree(new Key.ItemData(s));

			if(dt != null)
				wsd.readFromNBT(dt.asNbtCompound());
			
			synchronized(loaded)
			{
				loaded.put(s, wsd);
			}
	        
	    	return wsd;
        
		} catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}
    }

    public void setData(String s, WorldSavedData wsd)
    {    	
		synchronized(loaded)
		{
			loaded.put(s, wsd);
		}
    }
    
    public void saveAllData()
    {
		synchronized(loaded)
		{
	    	for(WorldSavedData wsd : loaded.values())
	    		if(wsd.isDirty())
	    		{
	    			saveData(wsd);
	    			wsd.setDirty(false);
	    		}
		}
    }

    private void saveData(WorldSavedData wsd)
    {    	
        NBTTagCompound nbt = new NBTTagCompound();
        wsd.writeToNBT(nbt);
        
        try
		{
			provider.writeDataTree(new DataTree(nbt), new Key.ItemData(wsd.mapName));
			
			wsd.setDirty(false);
		} catch(Exception e)
		{
			e.printStackTrace();
		}
    }

    public int getUniqueDataId(String s)
    {
    	try
		{
			return provider.nextUniqueID(s);
		} catch(Exception e)
		{
			e.printStackTrace();
			return 0;
		}
    }
}
